package org.gap.jseed.util;

import java.lang.reflect.Modifier;

import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import org.gap.jseed.NoSuchClassException;

public class ClassUtil {
	public static boolean hasField(CtClass declaringClass, String fieldName) {
		try {
			declaringClass.getField(fieldName);
			return true;
		} catch (NotFoundException nfe) {
			return false;
		}
	}
	
	public static boolean equalClass(Object first, Object second) {
		Class<?> firstClass = first.getClass();
		Class<?> secondClass = second.getClass();
		return equalClass(firstClass, secondClass);
	}
	
	public static boolean equalClass(Class<?> first, Class<?> second) {
		return first.equals(second);
	}
	
	public static boolean isMethodAbstract(CtMethod method) {
		return method.getMethodInfo().getCodeAttribute() != null;
	}

	public static boolean hasAbstractClass(CtClass childClass) {
		if (hasSuperClass(childClass)) {
			CtClass superClass = getSuperClass(childClass);
			return Modifier.isAbstract(superClass.getModifiers());
		}
		return false;
	}
	
	public static boolean hasSuperClass(CtClass childClass) {
		try {
			childClass.getSuperclass();
			return true;
		} catch(NotFoundException nfe) {
			return false;
		}
	}
	
	public static CtClass getSuperClass(CtClass childClass) {
		try {
			return childClass.getSuperclass();
		} catch(NotFoundException nfe) {
			throw new NoSuchClassException("There contains now super class for " + childClass.getName(), nfe);
		}
	}
		
	public static boolean hasInterfaces(CtClass implementingClass) {
		try {
			CtClass[] interfaces = implementingClass.getInterfaces();
			return interfaces.length > 0;
		} catch (NotFoundException nfe) {
			return false;
		}
	}
	
	public static CtClass[] getInterfaces(CtClass implementingClass) {
		try {
			return implementingClass.getInterfaces();
		} catch (NotFoundException nfe) {
			return new CtClass[]{};
		}
	}

	public static boolean isMethodDefinedOn(String methodName,
			CtClass implementation) {
		try {
			implementation.getDeclaredMethod(methodName);
			return true;
		} catch (NotFoundException nfe) {
			return false;
		}
	}
}
